/*
 * CdnTree.cpp
 *
 *  Created on: Apr 22, 2013
 *      Author: root
 */

#include "CdnTree.h"

/*
 * CdnTree class init
 */
CdnTree::CdnTree() {

	root.InitNode(-1,"root");
	create_flag = false;
}

/*
 * CdnTree class free
 */
CdnTree::~CdnTree() {

	/**
	 * add your code here
	 */
}

/**
 * cdn tree init
 */
int CdnTree::init()
{
	if(!svr_node_table.init_table())
		return FAILURE;

	if(!svr_node_list.init_list(true))
		return FAILURE;

	return SUCCESS;
}

/**
 * CreateCdnTree  by xml tree
 */
int CdnTree::CreateCdnTree(const char * xmltree)
{
	if(xmltree == NULL)
		return FAILURE;

	int ret = SUCCESS;
	TiXmlDocument cdndoc;
	cdndoc.Parse(xmltree);
	TiXmlHandle docHandle(&cdndoc);
	TiXmlElement * xElement = NULL;
	xElement =  docHandle.FirstChildElement("cdn").ToElement();
	if(xElement != NULL)
	{
		ret = StructCdnTree(xElement,&root);
	}

	return ret;
}

/*
* struct cdn tree
*/
int CdnTree::StructCdnTree(TiXmlElement  * pXmlNode,CdnArea * pCdnNode)
{
	if(pXmlNode == NULL || pCdnNode == NULL)
		return FAILURE;

	TiXmlElement * pChildXmlNode = pXmlNode->FirstChildElement();
	CdnArea * cdnnode = NULL;

	while(pChildXmlNode != NULL)
	{
		if(pChildXmlNode->Attribute("id") != NULL && pChildXmlNode->Attribute("name") != NULL)
		{
			int id = atoi(pChildXmlNode->Attribute("id"));
			if(memcmp(pChildXmlNode->Value(),"area",4) == 0)
			{
				cdnnode = new CdnArea();
				cdnnode->InitNode(id,pChildXmlNode->Attribute("name"));
				pCdnNode->ApendChildToLast(cdnnode);
			}
			else if(memcmp(pChildXmlNode->Value(),"room",4) == 0)
			{
				cdnnode = new CdnRoom();
				int id = atoi(pChildXmlNode->Attribute("id"));
				cdnnode->InitNode(id,pChildXmlNode->Attribute("name"));
				pCdnNode->ApendChildToLast(cdnnode);
			}
			else if(memcmp(pChildXmlNode->Value(),"node",4) == 0)
			{
				cdnnode = new CdnServerNode();
				int id = atoi(pChildXmlNode->Attribute("id"));
				cdnnode->InitNode(id,pChildXmlNode->Attribute("name"));
				pCdnNode->ApendChildToLast(cdnnode);

				/*
				 * store server node
				 * */
				this->store_server_node((CdnServerNode *) cdnnode);
			}
			else
			{
				/*
				 * add your code here
				 * */
			}

			/**
			 * child node
			 */
			if(cdnnode != NULL)
			{
				StructCdnTree(pChildXmlNode,cdnnode);
			}

		}

		/**next node*/
		cdnnode = NULL;
		pChildXmlNode = pChildXmlNode->NextSiblingElement();
	}

	return SUCCESS;
}

/*
*add svr node to hask table
*if false,and auto free node
*/
bool CdnTree::store_server_node(CdnServerNode * pNode)
{
	bool ret = false;
	svr_node_lock.Lock();
	{
		if(NULL != pNode && strlen(pNode->key) != 0)
		{
			pNode->key_index = svr_node_table.add(pNode,pNode->key);
			if(pNode->key_index >= 0)
			{
				ret = svr_node_list.push(pNode);
			}
		}
		svr_node_lock.Unlock();
	}
	return ret;
}


/**
 * find server node by name
 */
CdnServerNode * CdnTree::find_server_node(const char * name)
{
	if(NULL == name || strlen(name)== 0)
			return NULL;

	CdnServerNode * node =  NULL;
	svr_node_lock.Lock();
	{
		node =  svr_node_table.find(name);

		svr_node_lock.Unlock();
	}

	return node;
}

/*
*remove node
*/
int CdnTree::remove_server_node(const char * name)
{
	int nRet = FAILURE;
	if(NULL != name && strlen(name) > 0)
	{
		CdnServerNode *p_node = NULL;
		svr_node_lock.Lock();
		{
			p_node = svr_node_table.remove(name);
			if(svr_node_list.remove(p_node))
			{
				 nRet =  SUCCESS;
			}

			svr_node_lock.Unlock();
		}
	}
	return nRet;
}


